import * as crypto from 'crypto';
import { ExceptionMap } from 'src/constant';
import { ExceptionType } from 'src/interface';
import { Logger } from '@nestjs/common';
import * as moment from 'moment';
import 'moment/locale/zh-cn';
const FORMAT = 'YYYY-MM-DD HH:mm:ss';
moment.locale('zh-cn');

export const md5 = (str) => {
  const hash = crypto.createHash('md5');
  hash.update(str);
  return hash.digest('hex');
};

export const generateVerificationCode = () => {
  return Math.floor(Math.random() * 1000000)
    .toString()
    .padStart(6, '0');
};

/**
 * @description 通过statusCode获取异常对象
 * @param statusCodeInput
 * @returns
 */
export const getExceptionByStatusCode = (
  statusCodeInput: number,
): ExceptionType => {
  let exception;
  for (const prop in ExceptionMap) {
    const val = ExceptionMap[prop];
    const { statusCode } = val;
    if (statusCode === statusCodeInput) {
      exception = val;
      break;
    }
  }
  //如果没匹配到，使用Bad_Request
  if (!exception) {
    exception = ExceptionMap.Bad_Request;
  }
  return exception;
};

/**
 *
 * @param response http response
 * @param statusCode 响应码 404,409....
 * @param errorName 返回给客户端错误码  Not Found,Confict ....
 * @param message 返回给客户端的message字段错误信息
 * @param detail 返回给客户端的错误详细信息 默认为空
 * @param exception 原始的错误对象 Error类型或其派生类
 */
export function sendExceptionResponse({
  response,
  statusCode,
  errorName,
  message,
  detail = null,
  exception,
}) {
  const resJson = {
    error: errorName,
    message: message,
    detail: detail,
  };
  response.status(statusCode).json(resJson);
  const req = response.req;
  //日志信息
  const logFormat = ` 
    Request original url: ${req.originalUrl}
    Method: ${req.method}
    IP: ${req.ip}
    Parmas: ${JSON.stringify(req.params)}
    Headers${JSON.stringify(req.headers)}
    Body: ${JSON.stringify(req.body)}
    Message:${JSON.stringify(message)}
    Detail: ${JSON.stringify(detail)}
  `;
  //日志打印request信息、堆栈异常信息、异常类名
  const stack = exception.stack || '';
  Logger.error(logFormat, stack, exception.name);
}

export const DateUtils = {
  getDateFormatSymbols(format?: string): string {
    if (!format) {
      format = FORMAT;
    }
    return moment().format(format);
  },

  currentDate(): Date {
    return moment().toDate();
  },

  addMonths(month: number): string {
    return moment().add(month, 'months').format(FORMAT);
  },

  formatDate(momentInput: string, format?: string): string {
    if (!format) {
      format = FORMAT;
    }
    return moment(momentInput).format(format);
  },
  diff(momentInput: string): number {
    return moment().diff(momentInput, 'seconds', true);
  },
};
